A 12 Step Program to Quick Emailing Plots & Csvs
printr, summarytools::dfSummary, stargazer::stargazerDThighcharterleaflet), 시계열(dygraphs), ggplots(plotly)DT코로나19 대쉬보드를 제작하기 위해서 먼저 코로나19 데이터를 가져온다. 이를 flexdashboard를 주요 엔진삼아 대쉬보드를 제작하고 이를 gh-pages 웹사이트에 배포한다.
다행히 코로나19 데이터의 경우 coronavirus 데이터 팩키지가 제작되어 데이터 입수에 따른 공수를 절약할 수 있다.
대쉬보드 제작 흐름
데이터 과학 요소가 들어간 대쉬보드 제작을 위한 UI 설계안을 작성한다.
코로나19 대쉬보드 UI 설계
flexdashboard 배치도(layout)코로나19 대쉬보드 UI 설계
wireframe 작성한 것을 flexdashboard 문법에 맞춰 대쉬보드 구성요소를 적절히 배치시킨다.
flexdashboard 배치도(layout)
상기 flexdashboard 배치도(layout)를 작성하기 위한 R마크다운 대쉬보드 코드는 다음과 같다. valueBox를 상단에 배치하고 아래 두 그래프 역영에 각기 필요한 그래프를 넣어준다.
---
layout: page
title: "데이터 과학을 위한 저작도구: Computational Documents"
subtitle: "대쉬보드(Dashboard)"
author:
name: "[Tidyverse Korea](https://www.facebook.com/groups/tidyverse/)"
date: "2020-02-29"
output:
html_document:
toc: yes
toc_float: true
highlight: tango
code_folding: show
number_section: true
self_contained: true
editor_options:
chunk_output_type: console
---
전세계 {data-icon="fa-globe"}
===================================
Row {data-width=150}
--------------------------------------------
### 확진자수
```r
infected <- 100
valueBox(infected, icon = "fa-procedures")
```
### 사망자수
```r
death <- 20
valueBox(death, icon = "fa-skull")
```
### 회복자수
```r
recovered <- 30
valueBox(recovered,
icon = "fa-walking",
color = ifelse(recovered > 10, "warning", "primary"))
```
Column {data-height=350}
-------------------------------------
### Chart 1
### Chart 2
한국 {data-icon="fa-map"}
===================================
경주하는 막대 그래프(Racing Barchart)는 GDP 상위 15국 (1970-2017), 글로벌 브랜드 가치 상위 15사 (2000-2018)를 보면 시각적으로 변화를 파악하는데 편리하다. 이를 R로 시각화하며 어떨까? Gina Reynolds가 R-Ladies에서 이를 해냈습니다. 코드도 간결하고 애니메이션도 부드럽고 아름답습니다.
gapminder: 경주하는 막대그래프
gapminder 데이터셋을 사용하여 경주하는 막대그래프를 제작하려면 연도별 국가순위(Rank)를 계산하는 전처리 작업이 필요하다. 그 다음 facet_wrap() 함수를 사용하여 년도별 변경사항을 시각화한다. 그리고 나서 gganimate로 시각화면 되는 어쩌면 매우 단순한 과정이다.
gapminder 데이터 팩키지에서 데이터를 가져온다. 그리고 나서 년도별 인구가 많은 상위 10개국을 추려낸다.
정적 그래프 시각화에 사용될 테마(theme)을 한글 폰트와 함께 색상을 적절히 지정한다.
library(extrafont)
loadfonts()
gapminder_theme <- theme_classic(base_family = "NanumGothic") +
theme(axis.text.y = element_blank()) +
theme(axis.ticks.y = element_blank()) +
theme(axis.line.y = element_blank()) +
theme(legend.background = element_rect(fill = "gainsboro")) +
theme(plot.background = element_rect(fill = "gainsboro")) +
theme(panel.background = element_rect(fill = "gainsboro"))geom_rect()를 사용해서 국가별 상위 10국에 대한 인구를 막대그래프로 표현하고, facet_wrap을 활용하여 년도별 인구변화를 작은 그래프로 만들어낸다. 그리고 국가명도 순서에 맞춰 붙여낸다.
gapminder_plot <- ranked_by_year %>%
ggplot() +
aes(xmin = 0 ,
xmax = pop / 1000000) +
aes(ymin = rank - .45,
ymax = rank + .45,
y = rank) +
facet_wrap(~ year) +
geom_rect(alpha = .7) +
aes(fill = continent) +
scale_fill_viridis_d(option = "magma",
direction = -1) +
scale_x_continuous(
limits = c(-355, 1400),
breaks = c(0, 400, 800, 1200)) +
geom_text(col = "gray13",
hjust = "right",
aes(label = country),
x = -50) +
scale_y_reverse() +
labs(fill = NULL) +
labs(x = '인구 (백만)') +
labs(y = "") +
gapminder_theme
gapminder_plotcoronavirus 데이터 팩키지에서 가져온 코로나 관련 데이터를 “경주하는 막대그프”로 생성하여 그래프 구성요소로 넣기 위해서 앞선 gapminder 경주 막대그래프 사례를 참조하여 데이터를 준비하고, 정적그래프에 이어서 애니메이션을 작성하여 .gif로 떨구고 이를 대쉬보드에서 불러 그래프 영역에 채워넣는다.
library(gganimate)
options(gganimate.nframes = 100)
## 데이터
corona_ranked_by_date <- coronavirus %>%
filter(type == 'confirmed') %>%
group_by(country, date) %>%
summarise(confirmed = sum(cases)) %>%
ungroup() %>%
group_by(country) %>%
arrange(date) %>%
mutate(cum_confirmed = cumsum(confirmed)) %>% # 국가별 누적환자수
ungroup() %>%
group_by(date) %>%
arrange(date, -cum_confirmed) %>% # 일별 상위 국가 선정
mutate(rank = 1:n()) %>%
filter(rank <=7) %>%
ungroup()
## 테마
library(extrafont)
loadfonts()
corona_theme <- theme_classic(base_family = "NanumGothic") +
theme(legend.position = "none") +
theme(axis.text.y = element_blank()) +
theme(axis.ticks.y = element_blank()) +
theme(axis.line.y = element_blank()) +
theme(legend.background = element_rect(fill = "gainsboro")) +
theme(plot.background = element_rect(fill = "gainsboro")) +
theme(panel.background = element_rect(fill = "gainsboro"))
corona_plot <- corona_ranked_by_date %>%
ggplot() +
aes(xmin = 0 ,
xmax = cum_confirmed) +
aes(ymin = rank - .45,
ymax = rank + .45,
y = rank) +
facet_wrap(~date) +
geom_rect(alpha = .7) +
aes(fill = country) +
scale_fill_viridis_d(option = "magma",
direction = -1) +
scale_x_continuous(
limits = c(-15000, 80000)) +
geom_text(col = "gray13",
hjust = "right",
aes(label = country),
x = -50) +
labs(fill = NULL) +
labs(x = '감염자수') +
labs(y = "") +
scale_y_reverse() +
corona_theme
corona_gif <- corona_plot +
facet_null() +
aes(group = country) +
geom_text(x = 55000 , y = -7,
family = "NanumGothic",
aes(label = as.character(date) ),
size = 10, col = "grey18") +
gganimate::transition_time(date)
corona_gif # anim_save("fig/corona.gif", corona_gif, duration=0.1)공간정보 시각화를 위해서 leaflet을 활용하여 coronavirus에 포함된 위경도 정보에 매칭시켜 인터랙티브 시각화 정보를 완성한다.
library(leaflet)
library(janitor)
coronavirus %>%
mutate(geo_name = glue::glue("{country} {province}")) %>%
select(-country, -province) %>%
group_by(geo_name, lat, long, type) %>%
summarise(cases = sum(cases, na.rm = TRUE)) %>%
spread(type, cases, fill=0) %>%
leaflet() %>%
addTiles() %>%
addProviderTiles(providers$OpenStreetMap) %>%
addMarkers(lng=~long, lat=~lat, clusterOptions = markerClusterOptions(),
popup = ~ as.character(paste0("<strong> 코로나19 현황: ", geo_name, "</strong><br>",
"-----------------------------------------------------------<br>",
"· 감염: ", scales::comma(confirmed), "<br>",
"· 사망: ", scales::comma(death), "<br>",
"· 회복: ", scales::comma(recovered), "<br>")))